﻿// -----------------------------------------------------------------------
// <copyright file="NotificationManager.cs" company="The Usual Dosage">
// © 2013 by Matthew M. Martin
// </copyright>
// -----------------------------------------------------------------------

namespace Cadence.NET.Notifications
{
    using System;
    using System.Linq;
    using Cadence.NET.Attributes;
    using Cadence.NET.BaseClasses;
    using log4net;
    using Cadence.NET.Interfaces;

    /// <summary>
    /// Derives the notification method from the attribute and sends a message to the right provider in the right context.
    /// </summary>
    public class NotificationManager
    {
        #region Private Members

        /// <summary>
        /// Gets a reference to the Log4Net logger
        /// </summary>
        protected static readonly ILog log = LogManager.GetLogger(typeof(CadenceTaskManager));

        #endregion Private Members

        #region Public Methods

        /// <summary>
        /// Processes the notification.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="behavior">The behavior.</param>
        /// <param name="eventType">Type of the event.</param>
        public void ProcessNotification(ITaskContext context, NotificationBehavior behavior, Cadence.NET.Attributes.NotificationBehavior.NotifyEvent eventType)
        {
            string duration = context.RunDuration.HasValue ? string.Format(" (Duration: {0}h {1}m {2}s {3}ms",
                                    context.RunDuration.Value.Hours, context.RunDuration.Value.Minutes,
                                    context.RunDuration.Value.Seconds, context.RunDuration.Value.Milliseconds) : string.Empty;

            switch (eventType)
            {
                case NotificationBehavior.NotifyEvent.TaskError:
                    {
                        // If the task has errored and is set to notify on error, send an email or push or both
                        if (behavior.NotifyOnTaskError)
                        {
                            if (behavior.NotificationMethods.Contains(NotificationBehavior.NotifyMethod.Email))
                            {
                                SendEmail(string.Format("{0} - {1}{2}", DateTime.Now.ToString(), context.ErrorContext.ToString(), duration));
                            }

                            if (behavior.NotificationMethods.Contains(NotificationBehavior.NotifyMethod.Pushover))
                            {
                                SendPushover(string.Format("{0} - {1}{2}", DateTime.Now.ToString(), context.ErrorContext.ToString(), duration));
                            }
                        }
                        break;
                    }
                case NotificationBehavior.NotifyEvent.TaskStart:
                    {
                        // If the task has started and is set to notify on start, send an email or push or both
                        if (behavior.NotifyOnTaskStart)
                        {
                            if (behavior.NotificationMethods.Contains(NotificationBehavior.NotifyMethod.Email))
                            {
                                SendEmail(string.Format("{0} - {1}{2}", DateTime.Now.ToString(), context.TaskStartedNotificationMessage, duration));
                            }

                            if (behavior.NotificationMethods.Contains(NotificationBehavior.NotifyMethod.Pushover))
                            {
                                SendPushover(string.Format("{0} - {1}{2}", DateTime.Now.ToString(), context.TaskStartedNotificationMessage, duration));
                            }
                        }
                        break;
                    }
                case NotificationBehavior.NotifyEvent.TaskStop:
                    {
                        // If the task has stopped and is set to notify on stop, send an email or push
                        if (behavior.NotifyOnTaskComplete)
                        {
                            if (behavior.NotificationMethods.Contains(NotificationBehavior.NotifyMethod.Email))
                            {
                                SendEmail(string.Format("{0} - {1}{2}", DateTime.Now.ToString(), context.TaskCompletedNotificationMessage, duration));
                            }

                            if (behavior.NotificationMethods.Contains(NotificationBehavior.NotifyMethod.Pushover))
                            {
                                SendPushover(string.Format("{0} - {1}{2}", DateTime.Now.ToString(), context.TaskCompletedNotificationMessage, duration));
                            }
                        }
                        break;
                    }
            }
        }

        #endregion Public Methods

        #region Private Methods

        /// <summary>
        /// Sends the pushover.
        /// </summary>
        /// <param name="message">The message.</param>
        private void SendPushover(string message)
        {
            try
            {
                new Pushover().Send(message);
                log.InfoFormat("SendPushover Succeeded : \"{0}\"", message);
            }
            catch (Exception exc)
            {
                log.Error(exc);
            }
        }

        /// <summary>
        /// Sends the email.
        /// </summary>
        /// <param name="message">The message.</param>
        private void SendEmail(string message)
        {
            try
            {
                new Email().Send(message);
                log.InfoFormat("SendEmail Succeeded : \"{0}\"", message);
            }
            catch (Exception exc)
            {
                log.Error(exc);
            }
        }

        #endregion Private Methods
    }
}
